package com.yourenbang.lingyun.transaction.web.service.impl.pay.transaction;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.yourenbang.lingyun.constants.BizCodeMessages;
import com.yourenbang.lingyun.core.config.datasource.DataSources;
import com.yourenbang.lingyun.core.config.datasource.RoutingDataSource;
import com.yourenbang.lingyun.core.message.Result;
import com.yourenbang.lingyun.core.util.KLog;
import com.yourenbang.lingyun.mapper.TerminalHistory21Mapper;
import com.yourenbang.lingyun.mapper.UserMerchantRecommend21Mapper;
import com.yourenbang.lingyun.transaction.mapper.TransactionPayTransactionMapper;
import com.yourenbang.lingyun.transaction.web.domain.dto.dy.QueryTradeDTO;
import com.yourenbang.terminal.api.service.RpcYxyTerminalService;
import com.yourenbang.transaction.api.model.dto.pay.CommonQueryTradeDTO;
import com.yourenbang.transaction.api.model.dto.transaction.QueryMerchantLastProfitDTO;
import com.yourenbang.transaction.api.model.dto.transaction.QueryMerchantProfitTransactionAmountDTO;
import com.yourenbang.transaction.api.model.vo.pay.DyPayTransactionPO;
import com.yourenbang.transaction.api.model.vo.pay.PayTransaction;
import com.yourenbang.transaction.api.model.vo.pay.ProfitTransactionAmountVO;
import com.yourenbang.transaction.api.service.pay.PayTypeApiService;
import com.yourenbang.transaction.api.service.pay.transaction.TransactionQueryService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.Callable;
import java.util.concurrent.Future;

@Slf4j
@RestController
public class TransactionQueryServiceImpl implements TransactionQueryService {

    @Autowired
    RpcYxyTerminalService rpcYxyTerminalService;
    @Autowired
    UserMerchantRecommend21Mapper userMerchantRecommend21Mapper;
    @Autowired
    TerminalHistory21Mapper terminalHistory21Mapper;
    @Autowired
    private DyPayTransactionFormatServiceImpl payTransactionFormatService;
    @Autowired
    private PayTypeApiService payTypeApiService;
    @Autowired
    ThreadPoolTaskExecutor taskExecutor;
    @Autowired
    TransactionPayTransactionMapper transactionPayTransactionMapper;

    private static final String DINAYIN_TRADE_V2_PATH = "/front/tarns/v2/list";
    private static final Integer DINAYIN_TRADE_PAGE_LIMIT = 200;
    private static final String DIANYIN_SUCCESS_CODE = "0000";

    @Override
    public Result<List<DyPayTransactionPO>> tradeList(CommonQueryTradeDTO dto) {
        KLog.info("下游查询交易入参:{}",dto.toJSON());
        if (Integer.valueOf(dto.getPageSize()) > DINAYIN_TRADE_PAGE_LIMIT) {
            return Result.builder().fail(BizCodeMessages.VALIDATOR_ERR, "页条数最大支持200条");
        }
//        Map<String, String> typeParam = payTypeApiService.getPayParams(PayTypeEnum.DIANYIN_TAIDIAN, PayFromEnum.merchant);
        QueryTradeDTO dyQueryDTO = new QueryTradeDTO();
//        dyQueryDTO.setORG_NO(typeParam.get("orgNo"));
        dyQueryDTO.setBEG_TIME(dto.getBeginTime());
        dyQueryDTO.setEND_TIME(dto.getEndTime());
        dyQueryDTO.setPAGE_NUM(dto.getPageNum());
        dyQueryDTO.setPAGE_SIZE(dto.getPageSize());

        //太点从电银直接拉完格式化
        JSONObject jsonObject = new JSONObject();// payTransactionFormatService.dyUrlRequestByPayType(DINAYIN_TRADE_V2_PATH, JSONObject.parseObject(JSONObject.toJSONString(dyQueryDTO), Map.class),PayTypeEnum.DIANYIN_TAIDIAN);
        if (!DIANYIN_SUCCESS_CODE.equals(jsonObject.getJSONObject("head").getString("respCode"))){
            KLog.info("下游交易数据接口返回失败,查询完毕");
            return Result.builder().fail(BizCodeMessages.TRANSACTION_UPSTREAM_QUERY_ERROR);
        }
        JSONObject listObj = jsonObject.getJSONObject("body").getJSONObject("data").getJSONObject("list");
        if (Objects.isNull(listObj)) {
            KLog.info("下游电银交易数据查询完毕");
            return Result.builder().fail(BizCodeMessages.TRANSACTION_UPSTREAM_QUERY_ERROR);
        }
        JSONArray jsonArray = listObj.getJSONArray("list");
        List<JSONObject> listVOS = jsonArray.toJavaList(JSONObject.class);
        if (CollectionUtils.isEmpty(listVOS)) {
            KLog.info("下游电银交易数据查询完毕");
            return Result.builder().success(new ArrayList<>());
        }
        List<DyPayTransactionPO> payTransactionList = new ArrayList<>();
        for (JSONObject listVO : listVOS) {
            PayTransaction payTransaction = payTransactionFormatService.payTransactionFormat(listVO);
            DyPayTransactionPO dyPayTransactionPO = new DyPayTransactionPO();
            dyPayTransactionPO.setClientNo(dto.getClientNo());
            BeanUtils.copyProperties(payTransaction, dyPayTransactionPO);
            payTransactionList.add(dyPayTransactionPO);
        }
        return Result.builder().success(payTransactionList);
    }

    @RoutingDataSource(DataSources.SLAVE_DB)
    @Override
    public Result<List<DyPayTransactionPO>> getMerchantLastProfitTransaction(List<QueryMerchantLastProfitDTO> merchantInfos) {
        List<DyPayTransactionPO> transactionPOList = new ArrayList<>();
        if (CollectionUtils.isEmpty(merchantInfos)) {
            return Result.builder().success(transactionPOList);
        }
        List<Future<DyPayTransactionPO>> taskList = new ArrayList<>();
        for (QueryMerchantLastProfitDTO merchantNo : merchantInfos) {
            taskList.add(taskExecutor.submit(new QueryMerchantLastProfitTask(merchantNo)));
        }

        for (Future<DyPayTransactionPO> dyPayTransactionPOFuture : taskList) {
            try {
                DyPayTransactionPO transactionPO = dyPayTransactionPOFuture.get();
                if (Objects.nonNull(transactionPO)) {
                    transactionPOList.add(transactionPO);
                }
            } catch (Exception e) {
                KLog.warn("通过商户信息批量获取最后一笔，异常", e);
            }
        }
        return Result.builder().success(transactionPOList);
    }

    @RoutingDataSource(DataSources.SLAVE_DB)
    @Override
    public Result<List<ProfitTransactionAmountVO>> getMerchantProfitTransactionAmount(QueryMerchantProfitTransactionAmountDTO dto) {
        List<ProfitTransactionAmountVO> transactionPOList = new ArrayList<>();
        if (CollectionUtils.isEmpty(dto.getMerchantList())) {
            return Result.builder().success(transactionPOList);
        }
        List<Future<ProfitTransactionAmountVO>> taskList = new ArrayList<>();
        for (QueryMerchantProfitTransactionAmountDTO.QueryMerchantInfo merchantInfo : dto.getMerchantList()) {
            taskList.add(taskExecutor.submit(new QueryMerchantProfitTransactionAmountTask(merchantInfo.getUserBaseId(), merchantInfo.getMerchantNo(), dto.getMonth())));
        }

        for (Future<ProfitTransactionAmountVO> profitTransactionAmountVO : taskList) {
            try {
                ProfitTransactionAmountVO transactionPO = profitTransactionAmountVO.get();
                if (Objects.nonNull(transactionPO)) {
                    transactionPOList.add(transactionPO);
                }
            } catch (Exception e) {
                KLog.warn("通过商户信息批量获取最后一笔，异常", e);
            }
        }
        return Result.builder().success(transactionPOList);
    }

    /**
     * 查询最后一笔分润交易的任务实现
     */
    class QueryMerchantLastProfitTask implements Callable<DyPayTransactionPO> {
        QueryMerchantLastProfitDTO queryParam;

        public QueryMerchantLastProfitTask(QueryMerchantLastProfitDTO queryParam) {
            this.queryParam = queryParam;
        }
        @Override
        public DyPayTransactionPO call() throws Exception {
            return transactionPayTransactionMapper.getMerchantLastProfitTransaction(
                    PayTransactionConfig.getTransTableIndex(queryParam.getUserBaseId()), queryParam.getMerchantNo(),
                    queryParam.getProfitFlag());
        }
    }

    /**
     * 查询分润交易额任务
     */
    class QueryMerchantProfitTransactionAmountTask implements Callable<ProfitTransactionAmountVO> {
        private String userBaseId;
        private String merchantNo;
        private String month;

        public QueryMerchantProfitTransactionAmountTask(String userBaseId, String merchantNo, String month) {
            this.userBaseId=userBaseId;
            this.merchantNo = merchantNo;
            this.month = month;
        }
        @Override
        public ProfitTransactionAmountVO call() throws Exception {
            return transactionPayTransactionMapper.getMerchantProfitTransactionAmount(
                    PayTransactionConfig.getTransTableIndex(this.userBaseId), this.merchantNo, this.month);
        }
    }
}
